using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using SynapseGaming.LightingSystem.Effects.Forward;
using SynapseGaming.LightingSystem.Effects;
using SynapseGaming.LightingSystem.Core;

namespace The_LarX.Rendering
{
    public class Material
    {
        #region Variables
        
#if !WINDOWS_PHONE        
        #region SunBurn Rendering Vars
        public Vector4 DiffuseColor
        {
            get { return Effect.Parameters[EffectLink_DiffuseColor].GetValueVector4(); }
            set { Effect.Parameters[EffectLink_DiffuseColor].SetValue(value); }
        }
        public Vector4 EmissiveColor
        {
            get { return Effect.Parameters[EffectLink_EmissiveColor].GetValueVector4(); }
            set {  Effect.Parameters[EffectLink_EmissiveColor].SetValue(value); }
        }
        public Vector4 SpecularAndAmount
        {
            get { return Effect.Parameters[EffectLink_SpecularAndAmount].GetValueVector4(); }
            set {  Effect.Parameters[EffectLink_SpecularAndAmount].SetValue(value); }
        }
        public Texture2D NormalMapTexture
        {
            get { return Effect.Parameters[EffectLink_NormalMapTexture].GetValueTexture2D(); }
            set {  Effect.Parameters[EffectLink_NormalMapTexture].SetValue(value); }
        }
        public Texture2D DiffuseMapTexture
        {
            get { return Effect.Parameters[EffectLink_DiffuseMapTexture].GetValueTexture2D(); }
            set {  Effect.Parameters[EffectLink_DiffuseMapTexture].SetValue(value); }
        }
        public Texture2D EmissiveMapTexture
        {
            get { return Effect.Parameters[EffectLink_EmissiveMapTexture].GetValueTexture2D(); }
            set {  Effect.Parameters[EffectLink_EmissiveMapTexture].SetValue(value); }
        }
        public Texture2D SpecularColorMapTexture
        {
            get { return Effect.Parameters[EffectLink_SpecularColorMapTexture].GetValueTexture2D(); }
            set {  Effect.Parameters[EffectLink_SpecularColorMapTexture].SetValue(value); }
        }
        public Texture2D ParalaxMapTexture
        {
            get { return Effect.Parameters[EffectLink_ParalaxMapTexture].GetValueTexture2D(); }
            set {  Effect.Parameters[EffectLink_ParalaxMapTexture].SetValue(value); }
        }
        #endregion

        #region Lighting Maps

        public bool DoubleSided
        {
            get
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    return effect.DoubleSided;
                }
                return false;
            }
            set
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    effect.DoubleSided = value;
                }
            }
        }
        public float Transparency
        {
            get
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    return effect.Transparency;
                }
                return 0;
            }
            set
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    effect.Transparency = value;
                }
            }
        }
        public TransparencyMode TransparencyMode
        {
            get
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    return effect.TransparencyMode;
                }
                return 0;
            }
            set
            {
                if (Effect is BaseMaterialEffect)
                {
                    BaseMaterialEffect effect = Effect as BaseMaterialEffect;
                    effect.TransparencyMode = value;
                }
            }
        }
        private string transMap;
        public string TransparencyMap
        {
            get { return transMap; }
            set
            {
                if (Effect is LightingEffect)
                {
                    LightingEffect effect = Effect as LightingEffect;
                    effect.TransparencyMap = Engine.Content.Load<Texture2D>(value);
                    this.transMap = value;
                }
            }
        }

        

#endregion

        #region Texture by Name

        public string NormalMapTextureName
        {
            get { return normalMapTextureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    NormalMapTexture = Engine.Content.Load<Texture2D>(value);
                }
                this.normalMapTextureName = value;
            }
        }
        private string normalMapTextureName;

        public string EmissiveMapTextureName
        {
            get { return emissiveMaptextureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    EmissiveMapTexture = Engine.Content.Load<Texture2D>(value);
                }
                this.emissiveMaptextureName = value;
            }
        }
        private string emissiveMaptextureName;

        public string SpecularMapTextureName
        {
            get { return specularMaptextureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    SpecularColorMapTexture = Engine.Content.Load<Texture2D>(value);
                }
                this.specularMaptextureName = value;
            }
        }
        private string specularMaptextureName;

        public string ParalaxMapTextureName
        {
            get { return paralaxMaptextureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    ParalaxMapTexture = Engine.Content.Load<Texture2D>(value);
                }
                this.paralaxMaptextureName = value;
            }
        }
        private string paralaxMaptextureName;


        public string TextureName
        {
            get { return textureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    DiffuseMapTexture = Engine.Content.Load<Texture2D>(value);
                }
                this.textureName = value;
            }
        }
        private string textureName;
        #endregion

#else
        public Vector4 DiffuseColor
        {
            get { return new Vector4(Effect.DiffuseColor, 0); }
            set { Effect.DiffuseColor = Vector3Util.Vector4ToVector3(value); }
        }
        public Vector3 DiffuseColor3
        {
            get { return Effect.DiffuseColor; }
            set { Effect.DiffuseColor = value; }
        }
        public Vector4 EmissiveColor
        {
            get { return new Vector4(Effect.EmissiveColor, 0); }
            set { Effect.EmissiveColor = Vector3Util.Vector4ToVector3(value); }
        }
        public Vector3 EmissiveColor3
        {
            get { return Effect.EmissiveColor; }
            set { Effect.EmissiveColor = value; }
        }
        public float Specular
        {
            get { return Effect.SpecularPower; }
            set { Effect.SpecularPower = value; }
        }
        public Vector3 SpecularColor
        {
            get { return Effect.SpecularColor; }
            set { Effect.SpecularColor = value; }
        }
        public Texture2D DiffuseMapTexture
        {
            get { return Effect.Texture; }
            set { Effect.Texture = value; }
        }
        public bool TextureEnabled
        {
            get { return Effect.TextureEnabled; }
            set { Effect.TextureEnabled = value; }
        }       

#endif


        public bool AlwaysDraw = false;

#if !WINDOWS_PHONE
        public Effect Effect;
#else
        public BasicEffect Effect;
#endif

        #endregion

        #region VariableLinks

        public static string EffectLink_DiffuseColor = "_DiffuseColor";
        public static string EffectLink_EmissiveColor = "_EmissiveColor";
        public static string EffectLink_SpecularAndAmount = "_SpecularPower_And_Amount";
        public static string EffectLink_NormalMapTexture = "_NormalMapTexture";
        public static string EffectLink_DiffuseMapTexture = "_DiffuseMapTexture";
        public static string EffectLink_EmissiveMapTexture = "_EmissiveMapTexture";
        public static string EffectLink_SpecularColorMapTexture = "_SpecularColorMapTexture";
        public static string EffectLink_ParalaxMapTexture = "_ParallaxMapTexture";

        #endregion

#if !WINDOWS_PHONE
        public Material(Effect effect) 
        {
            this.Effect = effect;
        }  
#else
        public Material(BasicEffect effect) 
        {
            this.Effect = effect;
        } 
#endif
        public virtual void SerializeData(int mi, SerializeData Data)
        {
#if !WINDOWS_PHONE
            Data.AddData(mi + "Material.DiffuseColor", DiffuseColor);
            Data.AddData(mi + "Material.EmissiveColor", EmissiveColor);
            Data.AddData(mi + "Material.SpecularAndAmount", SpecularAndAmount);
            Data.AddData(mi + "Material.NormalMapTexName", normalMapTextureName);
            Data.AddData(mi + "Material.TextureName", textureName);
            Data.AddData(mi + "Material.EmissiveMapTexName", emissiveMaptextureName);
            Data.AddData(mi + "Material.SpcularMapTexName", specularMaptextureName);
            Data.AddData(mi + "Material.ParalaxMapTextName", paralaxMaptextureName);

            if (this.Effect is LightingEffect)
            {
                LightingEffect fx = this.Effect as LightingEffect;
                Data.AddData(mi + "Material.DoubleSided", fx.DoubleSided);
                Data.AddData(mi + "Material.TransparencyMode", (int)this.TransparencyMode);
                Data.AddData(mi + "Material.Transparency", this.Transparency);
            }

#endif
        }

        public virtual void DeserializeData(int mi, SerializeData Data)
        {
#if !WINDOWS_PHONE
            this.EmissiveColor = Data.GetData<Vector4>(mi + "Material.EmissiveColor");
            this.SpecularAndAmount = Data.GetData<Vector4>(mi + "Material.SpecularAndAmount");
            this.NormalMapTextureName = Data.GetData<string>(mi + "Material.NormalMapTexName");
            this.TextureName = Data.GetData<string>(mi + "Material.TextureName");
            this.DiffuseColor = Data.GetData<Vector4>(mi + "Material.DiffuseColor");
            this.EmissiveMapTextureName = Data.GetData<string>(mi + "Material.EmissiveMapTexName");
            this.SpecularMapTextureName = Data.GetData<string>(mi + "Material.SpcularMapTexName");
            this.ParalaxMapTextureName = Data.GetData<string>(mi + "Material.ParalaxMapTextName");

            if (this.Effect is LightingEffect)
            {
                LightingEffect fx = this.Effect as LightingEffect;
                fx.DoubleSided = Data.GetData<bool>(mi + "Material.DoubleSided");
                fx.TransparencyMode = (TransparencyMode)Data.GetData<int>(mi + "Material.TransparencyMode");
                fx.Transparency = Data.GetData<float>(mi + "Material.Transparency");
            }            
#endif
        }
    }
}